//! # 配置加载器示例
//!
//! 演示如何使用配置加载器和配置源
//!
//! ## 运行方式
//!
//! ```bash
//! cargo run --example config_client
//! ```
//!
//! ## 功能演示
//!
//! 这个示例展示了：
//!
//! * 配置加载器的使用
//! * 不同配置格式的处理
//! * 配置源的优先级管理
//! * 错误处理和恢复策略

use std::time::Duration;
use tracing::{info, warn, error, Level};
use tracing_subscriber;

use rustcloud_config::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化日志
    tracing_subscriber::fmt()
        .with_max_level(Level::INFO)
        .init();

    info!("🚀 启动配置加载器示例...");

    // 创建测试配置文件
    create_test_configs().await?;

    // 演示配置加载器
    demo_config_loader().await?;

    // 演示配置格式检测
    demo_format_detection().await?;

    // 演示配置源管理
    demo_config_sources().await?;

    // 演示配置解析
    demo_config_parsing().await?;

    // 演示错误处理
    demo_error_handling().await?;

    info!("✅ 配置加载器示例完成");
    Ok(())
}

/// 创建测试配置文件
async fn create_test_configs() -> Result<(), Box<dyn std::error::Error>> {
    use std::fs;

    // 确保配置目录存在
    fs::create_dir_all("./client-config")?;

    // 创建基础配置
    let base_toml = r#"
[application]
name = "client-app"
version = "1.0.0"
port = 9000

[application.metadata]
env = "test"
owner = "dev-team"

[registry]
registry_type = "nacos"
server_addr = "127.0.0.1:8848"
"#;
    fs::write("./client-config/base.toml", base_toml)?;

    // 创建开发环境配置
    let dev_yaml = r#"
application:
  version: "1.0.0-dev"
  port: 9001
  metadata:
    env: "development"
    debug: "true"

registry:
  namespace: "development"
"#;
    fs::write("./client-config/dev.yaml", dev_yaml)?;

    // 创建生产环境配置
    let prod_json = r#"{
  "application": {
    "version": "1.0.0-prod",
    "port": 9002,
    "metadata": {
      "env": "production",
      "team": "ops"
    }
  },
  "registry": {
    "namespace": "production",
    "group": "stable"
  }
}"#;
    fs::write("./client-config/prod.json", prod_json)?;

    info!("📝 测试配置文件已创建");
    Ok(())
}

/// 演示配置加载器
async fn demo_config_loader() -> Result<(), Box<dyn std::error::Error>> {
    info!("🔧 演示配置加载器...");

    // 创建不同格式的配置加载器
    let toml_loader = ConfigLoader::new("./client-config/base.toml", ConfigFormat::Toml);
    let yaml_loader = ConfigLoader::new("./client-config/dev.yaml", ConfigFormat::Yaml);
    let json_loader = ConfigLoader::new("./client-config/prod.json", ConfigFormat::Json);

    // 加载TOML配置
    match toml_loader.load() {
        Ok(config) => {
            info!("✅ TOML加载器成功:");
            info!("   应用: {} v{}", config.application.name, config.application.version);
        }
        Err(e) => error!("❌ TOML加载失败: {}", e),
    }

    // 加载YAML配置
    match yaml_loader.load() {
        Ok(config) => {
            info!("✅ YAML加载器成功:");
            info!("   版本: {}", config.application.version);
            info!("   端口: {}", config.application.port);
        }
        Err(e) => error!("❌ YAML加载失败: {}", e),
    }

    // 加载JSON配置
    match json_loader.load() {
        Ok(config) => {
            info!("✅ JSON加载器成功:");
            info!("   版本: {}", config.application.version);
            info!("   命名空间: {:?}", config.registry.namespace);
        }
        Err(e) => error!("❌ JSON加载失败: {}", e),
    }

    Ok(())
}

/// 演示格式检测
async fn demo_format_detection() -> Result<(), Box<dyn std::error::Error>> {
    info!("🔍 演示格式检测...");

    let test_files = vec![
        "./client-config/base.toml",
        "./client-config/dev.yaml",
        "./client-config/prod.json",
    ];

    for file_path in test_files {
        match ConfigFormat::from_path(file_path) {
            Some(format) => {
                info!("✅ 检测到 {} 格式: {:?}", file_path, format);
                
                // 使用检测到的格式创建加载器
                let loader = ConfigLoader::new(file_path, format);
                match loader.load() {
                    Ok(config) => {
                        info!("   📖 成功加载: {}", config.application.name);
                    }
                    Err(e) => warn!("   ⚠️ 加载失败: {}", e),
                }
            }
            None => warn!("❓ 无法检测 {} 的格式", file_path),
        }
    }

    Ok(())
}

/// 演示配置源管理
async fn demo_config_sources() -> Result<(), Box<dyn std::error::Error>> {
    info!("📚 演示配置源管理...");

    // 创建不同优先级的配置源
    let base_source = ConfigSource::File {
        path: "./client-config/base.toml".to_string(),
        format: ConfigFormat::Toml,
    };
    let dev_source = ConfigSource::File {
        path: "./client-config/dev.yaml".to_string(),
        format: ConfigFormat::Yaml,
    };
    let prod_source = ConfigSource::File {
        path: "./client-config/prod.json".to_string(),
        format: ConfigFormat::Json,
    };

    info!("📋 配置源信息:");
    info!("   基础配置: 优先级 {}", base_source.priority());
    info!("   开发配置: 优先级 {}", dev_source.priority());
    info!("   生产配置: 优先级 {}", prod_source.priority());

    // 显示缓存键
    info!("🔑 缓存键:");
    info!("   基础: {}", base_source.cache_key());
    info!("   开发: {}", dev_source.cache_key());
    info!("   生产: {}", prod_source.cache_key());

    Ok(())
}

/// 演示配置解析
async fn demo_config_parsing() -> Result<(), Box<dyn std::error::Error>> {
    info!("🔧 演示配置解析...");

    // 测试不同内容的解析
    let toml_content = r#"
[application]
name = "test-service"
version = "0.1.0"
port = 8888

[application.metadata]
test = "true"
"#;

    let yaml_content = r#"
application:
  name: "yaml-service"
  version: "0.2.0"
  port: 8889
  metadata:
    format: "yaml"
"#;

    let json_content = r#"{
  "application": {
    "name": "json-service",
    "version": "0.3.0",
    "port": 8890,
    "metadata": {
      "format": "json"
    }
  }
}"#;

    // 解析TOML内容
    let toml_loader = ConfigLoader::new("dummy.toml", ConfigFormat::Toml);
    match toml_loader.parse_content(toml_content) {
        Ok(config) => {
            info!("✅ TOML内容解析成功: {} v{}", 
                config.application.name, config.application.version);
        }
        Err(e) => error!("❌ TOML解析失败: {}", e),
    }

    // 解析YAML内容
    let yaml_loader = ConfigLoader::new("dummy.yaml", ConfigFormat::Yaml);
    match yaml_loader.parse_content(yaml_content) {
        Ok(config) => {
            info!("✅ YAML内容解析成功: {} v{}", 
                config.application.name, config.application.version);
        }
        Err(e) => error!("❌ YAML解析失败: {}", e),
    }

    // 解析JSON内容
    let json_loader = ConfigLoader::new("dummy.json", ConfigFormat::Json);
    match json_loader.parse_content(json_content) {
        Ok(config) => {
            info!("✅ JSON内容解析成功: {} v{}", 
                config.application.name, config.application.version);
        }
        Err(e) => error!("❌ JSON解析失败: {}", e),
    }

    Ok(())
}

/// 演示错误处理
async fn demo_error_handling() -> Result<(), Box<dyn std::error::Error>> {
    info!("🚨 演示错误处理...");

    // 测试文件不存在
    let missing_loader = ConfigLoader::new("./non-existent.toml", ConfigFormat::Toml);
    match missing_loader.load() {
        Ok(_) => warn!("⚠️ 意外成功加载不存在的文件"),
        Err(e) => info!("✅ 正确处理文件不存在错误: {}", e),
    }

    // 测试格式错误
    use std::fs;
    fs::write("./client-config/invalid.toml", "invalid toml content {")?;
    
    let invalid_loader = ConfigLoader::new("./client-config/invalid.toml", ConfigFormat::Toml);
    match invalid_loader.load() {
        Ok(_) => warn!("⚠️ 意外成功解析无效内容"),
        Err(e) => info!("✅ 正确处理格式错误: {}", e),
    }

    // 清理
    let _ = fs::remove_file("./client-config/invalid.toml");

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_config_loader_demo() {
        create_test_configs().await.unwrap();
        demo_config_loader().await.unwrap();
    }

    #[tokio::test]
    async fn test_format_detection() {
        create_test_configs().await.unwrap();
        demo_format_detection().await.unwrap();
    }
}